package ua.lviv.franko.solvers.stressanalysis.twoDimention;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import ua.lviv.franko.integration.IFunction2D;
import ua.lviv.franko.mlsFunctions.twoDimension.BaseFunction;
import ua.lviv.franko.mlsFunctions.twoDimension.Particle;
import ua.lviv.franko.mlsFunctions.twoDimension.weightFunctions.IWeightFunction2D;
import ua.lviv.franko.solvers.stressanalysis.twoDimention.fem.LinearRectangularElement;
import ua.lviv.franko.triangulation.SaveStructures.Node;

public class EnrichedLinearRecagularElement extends LinearRectangularElement {

	protected List<Particle>		particles;
	protected List<BaseFunction>	efgBaseFunctions;

	public EnrichedLinearRecagularElement(Node A, Node B, Node C, Node D, double k1, double k2, double k3, IFunction2D f1Function, IFunction2D f2Function, int numBaseFunctions,
			double rho, int polinomialDegree, IWeightFunction2D weight) {
		super(A, B, C, D, k1, k2, k3, f1Function, f2Function);
		particles = new ArrayList<Particle>();

		double hx = (B.x - A.x) / (double) numBaseFunctions, hy = (C.y - A.y) / (double) numBaseFunctions;

		double rhoReal = rho * hx;
		for (int i = 0; i <= numBaseFunctions; i++) {
			for (int j = 0; j <= numBaseFunctions; j++) {
				Particle p = new Particle(A.x + i * hx, A.y + j * hy, rhoReal);
				particles.add(p);
			}
		}

		createBaseFunctions(polinomialDegree, weight);

	}

	@Override
	public ElementMatrixForStress generateAll() {

		return super.generateAll();
	}

	private void createBaseFunctions(int PolinomialDegree, IWeightFunction2D weight) {
		this.efgBaseFunctions = new ArrayList<BaseFunction>();
		for (Iterator<Particle> iterator = particles.iterator(); iterator.hasNext();) {
			Particle particle = iterator.next();
			BaseFunction bf = new BaseFunction(PolinomialDegree, particle, weight);
			bf.setNodeList(this.getParticleSupport(particle, weight));
			this.efgBaseFunctions.add(bf);
		}
	}

	private ArrayList<Particle> getParticleSupport(Particle p, IWeightFunction2D weight) {
		ArrayList<Particle> list = new ArrayList<Particle>();
		for (Iterator<Particle> iterator = particles.iterator(); iterator.hasNext();) {
			Particle particle = (Particle) iterator.next();
			if (weight.intersectedSupport(p, particle)) {
				list.add(particle);
			}
		}
		return list;
	}

}
